package dk.mirasola.systemtraining.bridgewidgets.client.ui;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.BiddingSequence;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.ContractBid;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.SpecialBid;

public class Bidbox extends Composite {
    private FlexTable contractBids;
    private Grid specialBids;
    private BidHandler bidHandler;
    private int biddableRow = -1;
    private int biddableCol = -1;
    private boolean canDouble;
    private boolean canRedouble;

    public Bidbox() {
        contractBids = new FlexTable();
        initWidget(contractBids);

        for (int level = 1; level <= 7; level++) {
            ContractBid[] bids = ContractBid.values(level);
            int col = 0;
            for (ContractBid bid : bids) {
                contractBids.getFlexCellFormatter().setWordWrap(level - 1, col, false);
                contractBids.setHTML(level - 1, col, RenderUtil.renderBid(bid));
                col++;
            }
        }

        contractBids.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                HTMLTable.Cell cell = contractBids.getCellForEvent(event);
                if (bidHandler != null && cell.getRowIndex() < 7) {
                    if ((cell.getRowIndex() == biddableRow && cell.getCellIndex() >= biddableCol) || cell.getRowIndex() > biddableRow) {
                        int level = cell.getRowIndex() + 1;
                        ContractBid.Call call = null;
                        if (cell.getCellIndex() == 0) {
                            call = ContractBid.Call.CLUB;
                        } else if (cell.getCellIndex() == 1) {
                            call = ContractBid.Call.DIAMOND;
                        } else if (cell.getCellIndex() == 2) {
                            call = ContractBid.Call.HEART;
                        } else if (cell.getCellIndex() == 3) {
                            call = ContractBid.Call.SPADE;
                        } else if (cell.getCellIndex() == 4) {
                            call = ContractBid.Call.NOTRUMPH;
                        }
                        bidHandler.onBid(ContractBid.get(level, call));
                    }
                }
            }
        });

        specialBids = new Grid(1, 3);
        specialBids.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                HTMLTable.Cell cell = specialBids.getCellForEvent(event);
                if (bidHandler != null) {
                    if (cell.getCellIndex() == 0) {
                        bidHandler.onBid(SpecialBid.PAS);
                    } else if (cell.getCellIndex() == 1 && canDouble) {
                        bidHandler.onBid(SpecialBid.DOUBLE);
                    } else if (cell.getCellIndex() == 2 && canRedouble) {
                        bidHandler.onBid(SpecialBid.REDOUBLE);
                    }
                }
            }
        });
        specialBids.setWidth("100%");
        specialBids.setHTML(0, 0, RenderUtil.renderBid(SpecialBid.PAS));
        specialBids.getCellFormatter().setWidth(0, 0, "33%");
        specialBids.setHTML(0, 1, RenderUtil.renderBid(SpecialBid.DOUBLE));
        specialBids.getCellFormatter().setWidth(0, 1, "33%");
        specialBids.setHTML(0, 2, RenderUtil.renderBid(SpecialBid.REDOUBLE));
        specialBids.getCellFormatter().setWidth(0, 2, "33%");

        int specialBidsRow = contractBids.getRowCount();
        contractBids.setWidget(specialBidsRow, 0, specialBids);
        contractBids.getFlexCellFormatter().setColSpan(specialBidsRow, 0, 5);
        contractBids.getFlexCellFormatter().setStyleName(specialBidsRow,0,"specialbidsCell");

        addStyleName("bidbox");
        specialBids.addStyleName("specialbids");
    }

    public void setBidHandler(BidHandler bidHandler) {
        this.bidHandler = bidHandler;
    }

    public void setBiddingSequence(BiddingSequence biddingSequence) {
        // contract bids
        biddableRow = getBiddableRow(biddingSequence);
        biddableCol = getBiddableCol(biddingSequence);
        canDouble = biddingSequence != null && biddingSequence.isBidLegal(SpecialBid.DOUBLE);
        canRedouble = biddingSequence != null && biddingSequence.isBidLegal(SpecialBid.REDOUBLE);
        for (int row = 0; row < contractBids.getRowCount() - 1; row++) {
            for (int col = 0; col < contractBids.getCellCount(row); col++) {
                if ((row == biddableRow && col >= biddableCol) || row > biddableRow) {
                    contractBids.getFlexCellFormatter().setStyleName(row, col, "contractbid-biddable");
                } else {
                    contractBids.getFlexCellFormatter().setStyleName(row, col, "contractbid-unbiddable");
                }
            }
        }

        // pas
        if (biddingSequence != null)
            specialBids.getCellFormatter().setStyleName(0, 0, "specialbid-biddable");
        else
            specialBids.getCellFormatter().setStyleName(0, 0, "specialbid-unbiddable");

        // double
        if (biddingSequence != null && biddingSequence.isBidLegal(SpecialBid.DOUBLE)) {
            specialBids.getCellFormatter().setStyleName(0, 1, "specialbid-biddable");
        } else {
            specialBids.getCellFormatter().setStyleName(0, 1, "specialbid-unbiddable");
        }

        if (biddingSequence != null && biddingSequence.isBidLegal(SpecialBid.REDOUBLE)) {
            specialBids.getCellFormatter().setStyleName(0, 2, "specialbid-biddable");
        } else {
            specialBids.getCellFormatter().setStyleName(0, 2, "specialbid-unbiddable");
        }
        specialBids.getCellFormatter().addStyleName(0, 2, "last-specialbid");
    }


    private int getBiddableRow(BiddingSequence biddingSequence) {
        if (biddingSequence == null || biddingSequence.isFinish()) {
            return 6;
        }

        ContractBid lastContractBid = biddingSequence.getLastContractBid();
        if (lastContractBid == null) {
            return 0;
        }

        if (ContractBid.Call.NOTRUMPH.equals(lastContractBid.getCall())) {
            return lastContractBid.getLevel();
        } else {
            return lastContractBid.getLevel() - 1;
        }
    }

    private int getBiddableCol(BiddingSequence biddingSequence) {
        if (biddingSequence == null || biddingSequence.isFinish()) {
            return 5;
        }
        ContractBid lastContractBid = biddingSequence.getLastContractBid();
        if (lastContractBid == null) {
            return 0;
        }

        if (ContractBid.Call.CLUB.equals(lastContractBid.getCall())) {
            return 1;
        } else if (ContractBid.Call.DIAMOND.equals(lastContractBid.getCall())) {
            return 2;
        } else if (ContractBid.Call.HEART.equals(lastContractBid.getCall())) {
            return 3;
        } else if (ContractBid.Call.SPADE.equals(lastContractBid.getCall())) {
            return 4;
        } else if (ContractBid.Call.NOTRUMPH.equals(lastContractBid.getCall())) {
            return (biddingSequence.getLastContractBid().getLevel() == 7 ? 5 : 0);
        } else {
            throw new RuntimeException("no call for bid");
        }
    }
}
